
#include <map>
#include <assert.h>
#include "gismap_handler.h"
#include "http_comm/http_client_pool.h"
#include "http_comm/http_request.h"
#include "http_comm/http_response.h"
#include "c2cplatform/library/web/url_helper.h"
#include "c2cplatform/library/the3/jsoncpp/json.h"

#include "c2cent/library/log/CWWLog2.h"
#include "c2cplatform/library/the3/itil/c2c_attr.h"
#include "c2cent/library/log/CWTimeElf3.h"

#include "gismap_globalconfig.h"
#include "gismapgatewayao_itil_def.h"

#include "erp/gis/comm/erp_gis_define.h"
#include "erp/gis/po/coordinatespo_gis.h"
#include "erp/gis/comm/erp_gis_func_define.h"
#include "erp/comm/erp_errno_define.h"

using namespace erp::comm;
using namespace erp::gis::po;
using namespace erp::gis::ao;
using namespace erp::gis::comm;
using namespace comm::http::custorm;
using namespace c2cplatform::library::web;
using namespace Json;

const uint32_t MAX_JSON_SIZE = 20480;

static const std::string URL_ADDR_FLAG = "input_addr";
static const std::string URL_CITY_FLAG = "input_city";
static const std::string strInvalidGoogleType[] = {"locality","political","route","country"};
static const std::string strInvalidGaodeLevel[] = {"GL_CITY","GL_DISTRICT","GL_LINE","GL_PROVINCE","GL_OTHER"};


static void ItilAlarm(const std::string& strAlarmMsg)
{
	char sAlarmMsg[128] = {0};
	snprintf(sAlarmMsg, sizeof(sAlarmMsg), "%s", strAlarmMsg.c_str());
	adv_attr_set2(E_ITIL_GISMAPGATEWAYAO_ALARM, sizeof(sAlarmMsg), sAlarmMsg);
}

static bool IsInArray(const std::string strArraySrc[], uint32_t dwSize, const std::string& strCheckedItem)
{
	for (uint32_t dwIdx = 0; dwIdx < dwSize; dwIdx++)
	{
		if (strArraySrc[dwIdx] == strCheckedItem)
		{
			return true;
		}
	}

	return false;
}

static std::string GetJsonBody(const std::string& strAllBody)
{
	size_t iFirstBrace = strAllBody.find_first_of("{");
	size_t iLastBrace  = strAllBody.find_last_of("}");

	if (std::string::npos == iFirstBrace ||
		std::string::npos == iLastBrace)
	{
		return "";
	}

	size_t iJsonLen = iLastBrace - iFirstBrace + 1;
	if (iJsonLen <= 0)
	{
		return "";
	}
	
	std::string strJson = strAllBody.substr(iFirstBrace, iLastBrace - iFirstBrace + 1);
	return strJson;
}

CGisMapHandler::CGisMapHandler()
{
}

CGisMapHandler::~CGisMapHandler()
{
	Destroy();
}

void CGisMapHandler::Destroy()
{
	std::map<uint32_t, CGisMapRequest* >::iterator it = m_mapGisMapRequest.begin();
	std::map<uint32_t, CGisMapRequest* >::iterator itEnd = m_mapGisMapRequest.end();
	for (; it != itEnd; it++)
	{
		if (NULL != it->second)
		{
			delete it->second;
			it->second = NULL;
		}
	}

	m_mapGisMapRequest.clear();
}


const std::string& CGisMapHandler::GetLastErrMsg() const
{
	return m_strErrMsg;
}

int CGisMapHandler::GetCoordinates(
		const SGisMapParam& stGisMapParam,
		std::vector<CCoordinatesPo>& vecCoordinates)
{
	int iRet = 0;

	std::map<uint32_t, CGisMapRequest*>::const_iterator it = m_mapGisMapRequest.find(stGisMapParam.dwApiType);
	if (it == m_mapGisMapRequest.end())
	{
		m_strErrMsg = "no map request for apitype";
		iRet = ERR_ERP_GIS_GATEWAY_INPUT_INVALiD;
		return iRet;
	}

	CGisMapRequest* pGisMapRequest = it->second;
	iRet = pGisMapRequest->DoRequest(stGisMapParam, vecCoordinates);
	if (0 != iRet)
	{
		m_strErrMsg = "do request failed " + pGisMapRequest->GetLastErrMsg();
		C2C_WW_LOG_ERR(-1, "errmsg:%s", m_strErrMsg.c_str());
		return iRet;
	}

	return 0;
}

CGisMapRequest::CGisMapRequest()
{
	m_pHttpClient = CHTTP_CLIENT_POOL->GetHttpClient();
}



CGisMapRequest::~CGisMapRequest()
{
	if (NULL != m_pHttpClient)
    {
        CHTTP_CLIENT_POOL->ReclaimHttpClient(m_pHttpClient);
        m_pHttpClient = NULL;
    }
}

const std::string& CGisMapRequest::GetLastErrMsg() const
{
	return m_strErrMsg;
}

int CGisMapRequest::DoRequest(const SGisMapParam& stGisMapParam, std::vector<CCoordinatesPo>& vecCoordinates)
{
	if (NULL == m_pHttpClient)
	{
		m_strErrMsg = "http client not initial";
		return -1;
	}

	C2C_TIME_ELF_ITIL oWTimeElf(C2C_WWLOG, __FUNCTION__);
	InitRequestParam(stGisMapParam);

	CHttpRequest oWebRequest;
	GenWebRequest(oWebRequest);

	C2C_WW_LOG_DEBUG("Request Info:%s", oWebRequest.GetFullUrl().c_str());

	CHttpResponse oWebResponse;
	int iRet = m_pHttpClient->Get(oWebRequest, oWebResponse);
	oWTimeElf.AddTimeMark("m_pHttpClient->Get()", iRet);
	if (0 != iRet)
	{
		Attr_API2(m_dwRequestErrItil, 1);
		m_dwRequestErrNum++;

		if (CGisMapGlobalConfig::GetSwitchProxyThreshold() > 0 &&
			m_dwRequestErrNum > CGisMapGlobalConfig::GetSwitchProxyThreshold())
		{
			uint32_t dwPreProxyPort = m_dwProxyPort;
			std::string strPreProxy = m_strProxy;
			
			RefleshProxy();
			
			// switch proxy. 
			char sAlarmMsg[128] = {0};
			snprintf(sAlarmMsg, sizeof(sAlarmMsg),
				"Send [%s] Request Failed Continue Num[%u] > [%u], Switch Proxy[%s:%u] To Proxy[%s:%u] ErrMsg:%s",
				m_strMapName.c_str(), m_dwRequestErrNum, CGisMapGlobalConfig::GetSwitchProxyThreshold(),
				strPreProxy.c_str(), dwPreProxyPort, m_strProxy.c_str(), m_dwProxyPort, m_pHttpClient->GetLastError().c_str());

			C2C_WW_LOG_ERR(-1, "Alarm:%s", sAlarmMsg);
			
			ItilAlarm(std::string(sAlarmMsg));
			m_dwRequestErrNum = 0;
		}
		
		m_strErrMsg = "Request Failed. " + m_pHttpClient->GetLastError();
		return ERR_ERP_GIS_GATEWAY_REQUEST_API_FAILED;
	}
	C2C_WW_LOG_DEBUG("Request OK. Response Body:%s", oWebResponse.GetBody().c_str());

	m_dwRequestErrNum = 0;

	std::string strUtf8;
	iRet = GbkToUtf8(oWebResponse.GetBody(), strUtf8);
	oWTimeElf.AddTimeMark("GbkToUtf8", iRet);
	if (iRet != 0)
	{
		Attr_API2(m_dwParseErrItil, 1);
		
		m_strErrMsg = "response body convert gbk to utf8 failed.";
		return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
	}
	
	iRet = ParseCoordinate(oWebResponse.GetBody(), vecCoordinates);
	oWTimeElf.AddTimeMark("ParseCoordinate", iRet);
	switch (iRet)
	{
		case ERR_ERP_GIS_GATEWAY_RESPONSE_INVALID:
			Attr_API2(m_dwInvalidErrItil, 1);
			return iRet;
			
		case ERR_ERP_GIS_GATEWAY_RESULT_CHECK_FAILED:
			Attr_API2(m_dwCheckErrItil, 1);
			return iRet;
			
		case ERR_ERP_GIS_GATEWAY_PARSE_FAILED:
			Attr_API2(m_dwParseErrItil, 1);
			return iRet;
			
		case ERR_ERP_GIS_GATEWAY_REQUEST_LIMITATION:
			Attr_API2(m_dwReqLimitedErrItil, 1);
			return iRet;
			
		default:
			Attr_API2(m_dwSuccessItil, 1);
			break;
	}
	
	return 0;
}

void CGisMapRequest::GenWebRequest(CHttpRequest& oWebRequest)
{
	if (m_pHttpClient == NULL)
	{
		return;
	}

	std::string strFullUrl = m_strUrlTemplate;
	size_t ipos = strFullUrl.find(URL_ADDR_FLAG);
	if (ipos != std::string::npos)
	{
		strFullUrl.replace(ipos, URL_ADDR_FLAG.length(), m_stGisMapParam.strAddress);
	}
	if (!m_stGisMapParam.strCity.empty())
	{
		ipos = strFullUrl.find(URL_CITY_FLAG);
        if(ipos != std::string::npos)
        {
		    strFullUrl.replace(ipos, URL_CITY_FLAG.length(), m_stGisMapParam.strCity);
        }
	}

	oWebRequest.SetMainUrl(strFullUrl);
	if (m_dwTimeout != 0)
	{
		oWebRequest.SetTimeout(m_dwTimeout);
	}
	
	if (!m_strProxy.empty())
	{
		m_pHttpClient->SetProxy(m_strProxy, m_dwProxyPort);
	}

	if (strFullUrl.find("https") != std::string::npos)
	{
		oWebRequest.EnableSSLVerify();
	}

	oWebRequest.AddHeader("Proxy-Connection", "keep-alive");
	oWebRequest.AddHeader("Connection", "keep-alive");
}

void CGisMapRequest::InitRequestParam(const SGisMapParam& stGisMapParam)
{
	// url encode
	m_stGisMapParam = stGisMapParam;

	std::string strAddress;
	std::string strCity;

	CUrlHelper::Encode(stGisMapParam.strAddress.c_str(), strAddress);
	CUrlHelper::Encode(stGisMapParam.strCity.c_str(), strCity);
	
	m_stGisMapParam.strAddress = strAddress;
	m_stGisMapParam.strCity    = strCity;
}

CSoSoRequest::CSoSoRequest() : CGisMapRequest()
{
	m_strUrlTemplate   = CGisMapGlobalConfig::GetSosoUrl();
	m_strProxy         = CGisMapGlobalConfig::GetSosoProxy();
	m_dwTimeout        = CGisMapGlobalConfig::GetSosoTimeout();
	m_dwProxyPort      = CGisMapGlobalConfig::GetSosoProxyPort();

	m_dwSuccessItil    = E_ITIL_GISMAPGATEWAYAO_SOSO_SUCC_NUM;
	m_dwRequestErrItil = E_ITIL_GISMAPGATEWAYAO_SOSO_REQUEST_FAILED_NUM;
	m_dwParseErrItil   = E_ITIL_GISMAPGATEWAYAO_SOSO_PARSE_FAILED_NUM;
	m_dwCheckErrItil   = E_ITIL_GISMAPGATEWAYAO_SOSO_CHECK_FAILED_NUM;
	m_dwInvalidErrItil = E_ITIL_GISMAPGATEWAYAO_SOSO_INVALID_NUM;

	m_strMapName = "SOSO";
}

void CSoSoRequest::RefleshProxy()
{
	CGisMapGlobalConfig::SwitchSosoProxy();

	m_strProxy         = CGisMapGlobalConfig::GetSosoProxy();
	m_dwProxyPort      = CGisMapGlobalConfig::GetSosoProxyPort();
}

/* soso json format:
 *{
 * "info":{
 *	 error:0
 *	},
 * "pois":[{
 *    "pointx": 113.929775,
 *    "pointy": 22.533341,
 *	   },
 *	   {
 *	   "pointx": 113.929775,
 *	   "pointy": 22.533341,
 *	   }
 *  ]
 *}
 */
int CSoSoRequest::ParseJsonData(
	const std::string& strJson,
	SJsonSoso& stJsonSoso)
{
	if (strJson.length() > MAX_JSON_SIZE)
	{
		m_strErrMsg = "soso response json result length overflow";
		return ERR_ERP_GIS_GATEWAY_JSON_OVERFLOW;
	}

	try {
		
		Json::Reader oJsonReader;
		Json::Value oRootValue(Json::objectValue);
		bool bParseSucc = oJsonReader.parse(strJson, oRootValue);
		if(!bParseSucc)
		{
			m_strErrMsg = "soso json reader paser err:" + oJsonReader.getFormatedErrorMessages();
			return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
		}

		if (oRootValue.empty())
		{
			m_strErrMsg = "soso response json invalid";
			return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
		}
		
		if (!oRootValue.isMember("info"))
		{
			m_strErrMsg = "soso response json no info found";
			return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
		}
		
		Json::Value oInfoValue = oRootValue["info"];
		if (!oInfoValue.empty() && oInfoValue.isMember("error") && oInfoValue["error"].isNumeric())
		{
			stJsonSoso.iError = oInfoValue["error"].asInt();
		}
		else
		{
			m_strErrMsg = "soso json error value not found";
			return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
		}

		if (stJsonSoso.iError != 0)
		{
			m_strErrMsg = "soso json return stat != 0";
			return ERR_ERP_GIS_GATEWAY_RESPONSE_INVALID;
		}
		
		if (!oRootValue.isMember("detail"))
		{
			m_strErrMsg = "soso json detail node not found";
			return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
		}
		Json::Value oDetailValue = oRootValue["detail"];
		if (oDetailValue.empty() || !oDetailValue.isMember("pois"))
		{
			m_strErrMsg = "soso json pois node not found";
			return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
		}
		Json::Value oPoisValue   = oDetailValue["pois"];
		uint32_t dwArraySize     = oPoisValue.size();
		SPoints stPoints;
		if (!oPoisValue.empty() && oPoisValue.isArray())
		{
			for (uint32_t dwIdx = 0; dwIdx < dwArraySize; dwIdx++)
			{	
				if (oPoisValue[dwIdx].empty())
				{
					C2C_WW_LOG_DEBUG("soso member not found");
					continue;
				}
				
				if (!oPoisValue[dwIdx].isMember("pointx") ||
					!oPoisValue[dwIdx].isMember("pointy"))
				{
					C2C_WW_LOG_DEBUG("soso points member not found");
					continue;
				}

				Json::Value oPointx = oPoisValue[dwIdx].get("pointx", 0);
				Json::Value oPointy = oPoisValue[dwIdx].get("pointy", 0);
				if (oPointx.isNumeric() && oPointy.isNumeric())
				{
					stPoints.strX = DoubleToString(oPointx.asDouble());
					stPoints.strY = DoubleToString(oPointy.asDouble()); 
				}
				
				if (stPoints.strY.empty() || stPoints.strY.empty())
				{
					continue;
				}

				stJsonSoso.vecPoints.push_back(stPoints);
			}
		}
	}
	catch (...)
	{
		m_strErrMsg = "catch exception, parse soso json failed.";
		return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
	}
	
	return 0;
}

int CSoSoRequest::ParseCoordinate(
	const std::string& strResponseBody,
	std::vector<CCoordinatesPo>& vecCoordinates)
{
	if (strResponseBody.empty())
	{
		m_strErrMsg = "soso response body empty.";
		return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
	}

	std::string strJson = GetJsonBody(strResponseBody);
	SJsonSoso stJsonSoso;
	int iRet = ParseJsonData(strJson, stJsonSoso);
	if (0 != iRet)
	{
		return iRet;
	}
	
	CCoordinatesPo oCoordinatePo;
	std::vector<SPoints>::const_iterator iter = stJsonSoso.vecPoints.begin();
	std::vector<SPoints>::const_iterator iterEnd = stJsonSoso.vecPoints.end();
	for (; iter != iterEnd; iter++)
	{
		oCoordinatePo.SetXPoint(iter->strX);
		oCoordinatePo.SetYPoint(iter->strY);
		
		vecCoordinates.push_back(oCoordinatePo);
	}
	
	return 0;
}


CSoSo2Request::CSoSo2Request():CGisMapRequest()
{
	m_strUrlTemplate   = CGisMapGlobalConfig::GetSoso2Url();
	m_strProxy         = CGisMapGlobalConfig::GetSoso2Proxy();
	m_dwTimeout        = CGisMapGlobalConfig::GetSoso2Timeout();
	m_dwProxyPort      = CGisMapGlobalConfig::GetSoso2ProxyPort();

	m_dwSuccessItil    = E_ITIL_GISMAPGATEWAYAO_SOSO2_SUCC_NUM;
	m_dwRequestErrItil = E_ITIL_GISMAPGATEWAYAO_SOSO2_REQUEST_FAILED_NUM;
	m_dwParseErrItil   = E_ITIL_GISMAPGATEWAYAO_SOSO2_PARSE_FAILED_NUM;
	m_dwCheckErrItil   = E_ITIL_GISMAPGATEWAYAO_SOSO2_CHECK_FAILED_NUM;
	m_dwInvalidErrItil = E_ITIL_GISMAPGATEWAYAO_SOSO2_INVALID_NUM;

	m_strMapName = "SOSO2";
}

void CSoSo2Request::RefleshProxy()
{
	CGisMapGlobalConfig::SwitchSoso2Proxy();

	m_strProxy         = CGisMapGlobalConfig::GetSoso2Proxy();
	m_dwProxyPort      = CGisMapGlobalConfig::GetSoso2ProxyPort();
}

/* soso2 json format
 * {
 *  "info": {
	  "error":0
	 },
	 "detail":{
	  "gps_type":"1",
	  "pointx":11.00
	  "pointy":12.00
	  "similarity":"1.000000"
	 }
 * }
*/
int CSoSo2Request::ParseJsonData(
	const std::string& strJson,
	SJsonSoso2& stJsonSoso2)
{
	if (strJson.length() > MAX_JSON_SIZE)
	{
		m_strErrMsg = "soso2 response json result length overflow";
		return ERR_ERP_GIS_GATEWAY_JSON_OVERFLOW;
	}

	try 
	{
		Json::Reader oJsonReader;
		Json::Value oRootValue(Json::objectValue);
		bool bParseSucc = oJsonReader.parse(strJson, oRootValue);
		if(!bParseSucc)
		{
			m_strErrMsg = "soso2 json reader paser err:" + oJsonReader.getFormatedErrorMessages();
			return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
		}
		C2C_WW_LOG_DEBUG("oJsonReader.parse OK");

		if (oRootValue.empty())
		{
			m_strErrMsg = "soso2 response value invalid ";
			return ERR_ERP_GIS_GATEWAY_RESPONSE_INVALID;
		}
		
		if (!oRootValue.isMember("info"))
		{
			m_strErrMsg = "soso2 response json no info found";
			return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
		}
		Json::Value oInfoValue = oRootValue["info"];
		if (!oInfoValue.empty() && oInfoValue.isMember("error") && oInfoValue["error"].isNumeric())
		{
			stJsonSoso2.iError = oInfoValue["error"].asInt();
		}
		else
		{
			m_strErrMsg = "soso2 json error value not found";
			return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
		}

		if (stJsonSoso2.iError != 0)
		{
			m_strErrMsg = "soso2 json return stat != 0";
			return ERR_ERP_GIS_GATEWAY_RESPONSE_INVALID;
		}
		
		if (!oRootValue.isMember("detail"))
		{
			m_strErrMsg = "soso2 json detail node not found";
			return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
		}
		Json::Value oDetailValue = oRootValue["detail"];
		if (oDetailValue.empty())
		{
			m_strErrMsg = "soso2 json detail empty";
			return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
		}

		SPoints stPoints;
		Json::Value oPointx = oDetailValue.get("pointx", "");
		Json::Value oPointy = oDetailValue.get("pointy", "");
		if (oPointx.isString() && oPointy.isString())
		{
			stPoints.strX = oPointx.asString();
			stPoints.strY = oPointy.asString();
			stJsonSoso2.stPoints = stPoints;
		}
		else
		{
			m_strErrMsg = "soso2 json point  not found";
			return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
		}
		
		if (!oDetailValue.isMember("gps_type") || 
			oDetailValue["gps_type"].empty() ||
			!oDetailValue["gps_type"].isString())
		{
			m_strErrMsg = "soso2 json gps_type not found";
			return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
		}
		stJsonSoso2.iGpsType = atoi(oDetailValue["gps_type"].asString().c_str());
		
		if (!oDetailValue.isMember("similarity") ||
			oDetailValue["similarity"].empty() ||
			!oDetailValue["similarity"].isString())
		{
			m_strErrMsg = "soso2 json similarity not found";
			return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
		}
		stJsonSoso2.dbSimilarity = atof(oDetailValue["similarity"].asString().c_str());
	}
	catch (...)
	{
		m_strErrMsg = "catch exception, parse soso2 json failed.";
		return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
	}
	
	return 0;
}

int CSoSo2Request::ParseCoordinate(
	const std::string& strResponseBody,
	std::vector<CCoordinatesPo>& vecCoordinates)
{
	if (strResponseBody.empty())
	{
		m_strErrMsg = "soso2 response body empty.";
		return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
	}
	
	std::string strJson = GetJsonBody(strResponseBody);
	
	SJsonSoso2 stJsonSoso2;
	int iRet = ParseJsonData(strJson, stJsonSoso2);
	if (0 != iRet)
	{
		return iRet;
	}
	
	if (!CheckJsonData(stJsonSoso2))
	{
		m_strErrMsg = "soso2 check json not fit";
		return ERR_ERP_GIS_GATEWAY_RESULT_CHECK_FAILED;
	}
	
	CCoordinatesPo oCoordinatePo;
	oCoordinatePo.SetXPoint(stJsonSoso2.stPoints.strX);
	oCoordinatePo.SetYPoint(stJsonSoso2.stPoints.strY);
	
	vecCoordinates.push_back(oCoordinatePo);
	return 0;
}

bool CSoSo2Request::CheckJsonData(const SJsonSoso2& stJsonSoso2)
{
	if (CGisMapGlobalConfig::GetSoso2CheckDataSwitch())
	{
		if (stJsonSoso2.iGpsType != 1 && 
			stJsonSoso2.iGpsType != 2 &&
			stJsonSoso2.dbSimilarity >= 0.3f)
		{
			return true;
		}

		return false;
	}

	return true;
}

CBaiduRequest::CBaiduRequest():CGisMapRequest()
{
	m_strUrlTemplate   = CGisMapGlobalConfig::GetBaiduUrl();
	m_strProxy = CGisMapGlobalConfig::GetBaiduProxy();

	m_dwTimeout   = CGisMapGlobalConfig::GetBaiduTimeout();
	m_dwProxyPort = CGisMapGlobalConfig::GetBaiduProxyPort();

	m_dwSuccessItil    = E_ITIL_GISMAPGATEWAYAO_BAIDU_SUCC_NUM;
	m_dwRequestErrItil = E_ITIL_GISMAPGATEWAYAO_BAIDU_REQUEST_FAILED_NUM;
	m_dwParseErrItil   = E_ITIL_GISMAPGATEWAYAO_BAIDU_PARSE_FAILED_NUM;
	m_dwCheckErrItil   = E_ITIL_GISMAPGATEWAYAO_BAIDU_CHECK_FAILED_NUM;
	m_dwInvalidErrItil = E_ITIL_GISMAPGATEWAYAO_BAIDU_INVALID_NUM;

	m_strMapName = "BAIDU";
}

void CBaiduRequest::RefleshProxy()
{
	CGisMapGlobalConfig::SwitchBaiduProxy();

	m_strProxy         = CGisMapGlobalConfig::GetBaiduProxy();
	m_dwProxyPort      = CGisMapGlobalConfig::GetBaiduProxyPort();
}

/* baidu json format
 *{
 *   "status":"OK",
 *   "result":{
 *       "location":{
 *           "lng":113.941181,
 *           "lat":22.546417
 *       },
 *       "precise":0,
 *       "confidence":80,
 *       "level":"\u5546\u52a1\u5927\u53a6"
 *  }
 *}
 */
int CBaiduRequest::ParseJsonData(
	const std::string& strJson,
	SJsonBaidu& stJsonBaidu)
{
	if (strJson.length() > MAX_JSON_SIZE)
	{
		m_strErrMsg = "baidu response json result length overflow";
		return ERR_ERP_GIS_GATEWAY_JSON_OVERFLOW;
	}

	try 
	{
		Json::Reader oJsonReader;
		Json::Value oRootValue(Json::objectValue);
		bool bParseSucc = oJsonReader.parse(strJson, oRootValue);
		if(!bParseSucc)
		{
			m_strErrMsg = "baidu json reader paser err:" + oJsonReader.getFormatedErrorMessages();
			return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
		}
		C2C_WW_LOG_DEBUG("oJsonReader.parse OK");

		if (oRootValue.empty())
		{
			m_strErrMsg = "baidu json empty";
			return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
		}
		
		if (oRootValue.isMember("status") && oRootValue["status"].isString())
		{
			stJsonBaidu.strStatus = oRootValue["status"].asString();
		}
		else
		{
			m_strErrMsg = "baidu json status value not found";
			return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
		}

		if (stJsonBaidu.strStatus != "OK")
		{
			m_strErrMsg = "baidu json return status != OK";
			return ERR_ERP_GIS_GATEWAY_RESPONSE_INVALID;
		}

		if (!oRootValue.isMember("result"))
		{
			m_strErrMsg = "baidu json result node not found";
			return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
		}
		Json::Value oResultValue = oRootValue["result"];
		if (oResultValue.empty() || !oResultValue.isMember("location"))
		{
			m_strErrMsg = "baidu json location not found";
			return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
		}

		Json::Value oLocationValue = oResultValue["location"];
		if (oLocationValue.empty() || 
			!oLocationValue.isMember("lng") ||
			!oLocationValue.isMember("lat"))
		{
			m_strErrMsg = "baidu json lng,lat not found";
			return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
		}

		if (oLocationValue["lng"].empty() ||
			oLocationValue["lat"].empty() ||
			!oLocationValue["lng"].isNumeric() ||
			!oLocationValue["lat"].isNumeric())
		{
			m_strErrMsg = "baidu json lng,lat invalid";
			return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
		}

		SPoints stPoints;
		stPoints.strX = DoubleToString(oLocationValue["lng"].asDouble());
		stPoints.strY = DoubleToString(oLocationValue["lat"].asDouble());
		stJsonBaidu.stLocation = stPoints;

		if (!oResultValue.isMember("precise") ||
			oResultValue["precise"].empty() ||
			!oResultValue["precise"].isNumeric())
		{
			m_strErrMsg = "baidu json precise not found";
			return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
		}
		
		stJsonBaidu.iPrecise = oResultValue["precise"].asInt();

		if (!oResultValue.isMember("confidence") ||
			oResultValue["confidence"].empty() ||
			!oResultValue["confidence"].isNumeric())
		{
			m_strErrMsg = "baidu json confidence not found";
			return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
		}
		stJsonBaidu.dbConfidence = oResultValue["confidence"].asDouble();

		if (!oResultValue.isMember("level") ||
			oResultValue["level"].empty() ||
			!oResultValue["level"].isString())
		{
			m_strErrMsg = "baidu json level not found";
			return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
		}
		stJsonBaidu.strLevel = oResultValue["level"].asString();
	}
	catch (...)
	{
		m_strErrMsg = "catch exception, parse baidu json failed.";
		return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
	}

	return 0;
}

int CBaiduRequest::ParseCoordinate(
	const std::string& strResponseBody,
	std::vector<CCoordinatesPo>& vecCoordinates)
{
	if (strResponseBody.empty())
	{
		m_strErrMsg = "response body empty.";
		return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
	}
	
	std::string strJson = GetJsonBody(strResponseBody);
	
	SJsonBaidu stJsonBaidu;
	int iRet = ParseJsonData(strJson, stJsonBaidu);
	if (0 != iRet)
	{
		C2C_WW_LOG_ERR(-1, "baidu errmsg:%s", m_strErrMsg.c_str());
		return iRet;
	}
	
	if (!CheckJsonData(stJsonBaidu))
	{
		m_strErrMsg = "baidu check json not fit";
		return ERR_ERP_GIS_GATEWAY_RESULT_CHECK_FAILED;
	}
	
	CCoordinatesPo oCoordinatePo;
	oCoordinatePo.SetXPoint(stJsonBaidu.stLocation.strX);
	oCoordinatePo.SetYPoint(stJsonBaidu.stLocation.strY);
	
	vecCoordinates.push_back(oCoordinatePo);
	return 0;
}

bool CBaiduRequest::CheckJsonData(const SJsonBaidu& stJsonBaidu)
{
	if (CGisMapGlobalConfig::GetBaiduCheckDataSwitch())
	{
		if (stJsonBaidu.strLevel != "区县" &&
			stJsonBaidu.dbConfidence > 42)
		{
			return true;
		}

		return false;
	}

	return true;
}

CGoogleRequest::CGoogleRequest():CGisMapRequest()
{
	m_strUrlTemplate   = CGisMapGlobalConfig::GetGoogleUrl();
	m_strProxy = CGisMapGlobalConfig::GetGoogleProxy();

	m_dwTimeout   = CGisMapGlobalConfig::GetGoogleTimeout();
	m_dwProxyPort = CGisMapGlobalConfig::GetGoogleProxyPort();

	m_dwSuccessItil    = E_ITIL_GISMAPGATEWAYAO_GOOGLE_SUCC_NUM;
	m_dwRequestErrItil = E_ITIL_GISMAPGATEWAYAO_GOOGLE_REQUEST_FAILED_NUM;
	m_dwParseErrItil   = E_ITIL_GISMAPGATEWAYAO_GOOGLE_PARSE_FAILED_NUM;
	m_dwCheckErrItil   = E_ITIL_GISMAPGATEWAYAO_GOOGLE_CHECK_FAILED_NUM;
	m_dwInvalidErrItil = E_ITIL_GISMAPGATEWAYAO_GOOGLE_INVALID_NUM;
	m_dwReqLimitedErrItil = E_ITIL_GISMAPGATEWAYAO_GOOGLE_REQ_LIMITED_NUM;

	m_strMapName = "GOOGLE";
}

void CGoogleRequest::RefleshProxy()
{
	CGisMapGlobalConfig::SwitchGoogleProxy();

	m_strProxy         = CGisMapGlobalConfig::GetGoogleProxy();
	m_dwProxyPort      = CGisMapGlobalConfig::GetGoogleProxyPort();
}


/* Google json format
{
   "results" : [
      {
         "geometry" : {
            "location" : {
               "lat" : -33.8750460,
               "lng" : 151.2052720
            }
         },
         "types" : [ "restaurant", "food", "establishment" ]
      },
      {
         "geometry" : {
            "location" : {
               "lat" : -33.8583790,
               "lng" : 151.2100270
            }
         },
         "types" : [ "cafe", "bar", "restaurant", "food", "establishment" ]
      }
	 ];
   "status" : "OK"
}
 */
int CGoogleRequest::ParseJsonData(
	const std::string& strJson,
	SJsonGoogle& stJsonGoogle)
{
	if (strJson.length() > MAX_JSON_SIZE)
	{
		m_strErrMsg = "google response json result length overflow";
		return ERR_ERP_GIS_GATEWAY_JSON_OVERFLOW;
	}

	try 
	{
		Json::Reader oJsonReader;
		Json::Value oRootValue(Json::objectValue);
		bool bParseSucc = oJsonReader.parse(strJson, oRootValue);
		if(!bParseSucc)
		{
			m_strErrMsg = "google json reader paser err:" + oJsonReader.getFormatedErrorMessages();
			return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
		}
		C2C_WW_LOG_DEBUG("oJsonReader.parse OK");

		if (oRootValue.empty())
		{
			m_strErrMsg = "google json empty";
			return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
		}
		
		if (oRootValue.isMember("status") &&
			!oRootValue["status"].empty() &&
			oRootValue["status"].isString())
		{
			stJsonGoogle.strStatus = oRootValue["status"].asString();
		}
		else
		{
			m_strErrMsg = "google json status value not found";
			return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
		}

		if (stJsonGoogle.strStatus == "OVER_QUERY_LIMIT")
		{
			m_strErrMsg = "google request quota limitation";
			return ERR_ERP_GIS_GATEWAY_REQUEST_LIMITATION;
		}
		
		if (stJsonGoogle.strStatus != "OK")
		{
			m_strErrMsg = "google json return status != OK";
			return ERR_ERP_GIS_GATEWAY_RESPONSE_INVALID;
		}
		
		if (!oRootValue.isMember("results"))
		{
			m_strErrMsg = "google json result node not found";
			return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
		}
		Json::Value oResultValue = oRootValue["results"];
		if (!oResultValue.empty() && oResultValue.isArray())
		{
			uint32_t dwResultSize = oResultValue.size();
			for (uint32_t dwIdx = 0; dwIdx < dwResultSize; dwIdx++)
			{
				SGoogleLocation oGoogleLocation;
				
				Json::Value oJsonNode = oResultValue[dwIdx];
				if (oJsonNode.empty())
				{
					continue;
				}
				
				if (oJsonNode.isMember("geometry"))
				{
					Json::Value oGeometryValue = oJsonNode["geometry"];
					if (!oGeometryValue.empty() && oGeometryValue.isMember("location"))
					{
						Json::Value oLocationValue = oGeometryValue["location"];
						if (!oLocationValue.empty() && 
							!oLocationValue.get("lng",0).empty() &&
							oLocationValue.get("lng", 0).isNumeric() &&
							!oLocationValue.get("lat",0).empty() &&
							oLocationValue.get("lat", 0).isNumeric())
						{
							oGoogleLocation.stLocation.strX = DoubleToString(oLocationValue.get("lng", 0).asDouble());
							oGoogleLocation.stLocation.strY = DoubleToString(oLocationValue.get("lat", 0).asDouble());
						}
					}
				}
				if (oJsonNode.isMember("types"))
				{
					Json::Value oTypeValue = oJsonNode["types"];
					if (!oTypeValue.empty() && oTypeValue.isArray())
					{
						for (uint32_t dwI = 0; dwI < oTypeValue.size(); dwI++)
						{
							if (!oTypeValue[dwI].empty() && oTypeValue[dwI].isString())
							{
								std::string strType = oTypeValue[dwI].asString();
								oGoogleLocation.vecTypes.push_back(strType);
							}
						}
					}
				}
				stJsonGoogle.vecLocations.push_back(oGoogleLocation);
			}
		}
	}
	catch (...)
	{
		m_strErrMsg = "catch exception, parse google json failed.";
		return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
	}
	
	return 0;
}

int CGoogleRequest::ParseCoordinate(
	const std::string& strResponseBody,
	std::vector<CCoordinatesPo>& vecCoordinates)
{
	if (strResponseBody.empty())
	{
		m_strErrMsg = "google response body empty.";
		return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
	}
	
	std::string strJson = GetJsonBody(strResponseBody);
	
	SJsonGoogle stJsonGoogle;
	int iRet = ParseJsonData(strJson, stJsonGoogle);
	if (0 != iRet)
	{
		return iRet;
	}
	
	FilterLocation(stJsonGoogle);
	if (stJsonGoogle.vecLocations.empty())
	{
		m_strErrMsg = "google check json not fit";		
		return ERR_ERP_GIS_GATEWAY_RESULT_CHECK_FAILED;
	}

	std::vector<SGoogleLocation>::const_iterator iter    = stJsonGoogle.vecLocations.begin();
	std::vector<SGoogleLocation>::const_iterator iterEnd = stJsonGoogle.vecLocations.end();
	for (; iter != iterEnd; iter++)
	{
		const SPoints& stPoints = iter->stLocation;
		CCoordinatesPo oCoordinatePo;
		oCoordinatePo.SetXPoint(stPoints.strX);
		oCoordinatePo.SetYPoint(stPoints.strY);
		vecCoordinates.push_back(oCoordinatePo);
	}
	
	return 0;
}

void CGoogleRequest::FilterLocation(SJsonGoogle& stJsonGoogle)
{
	if (!CGisMapGlobalConfig::GetGoogleCheckDataSwitch())
	{
		return;
	}
	
	uint32_t dwInvalidTypeSize = sizeof(strInvalidGoogleType)/sizeof(strInvalidGoogleType[0]);
	
	std::vector<SGoogleLocation> vecGoogleLocation;
	std::vector<SGoogleLocation>::const_iterator iter    = stJsonGoogle.vecLocations.begin();
	std::vector<SGoogleLocation>::const_iterator iterEnd = stJsonGoogle.vecLocations.end();
	for (; iter != iterEnd; iter++)
	{
		bool bInvalid = false;
		const std::vector<std::string>& vecType = iter->vecTypes;
		std::vector<std::string>::const_iterator iterType    = vecType.begin();
		std::vector<std::string>::const_iterator iterTypeEnd = vecType.end();
		for (; iterType != iterTypeEnd; iterType++)
		{
			if (IsInArray(strInvalidGoogleType, dwInvalidTypeSize, *iterType))
			{
				bInvalid = true;
				break;
			}
		}

		if (!bInvalid)
		{
			vecGoogleLocation.push_back(*iter);
		}
	}
	
	stJsonGoogle.vecLocations = vecGoogleLocation;
}

CAliyunRequest::CAliyunRequest():CGisMapRequest()
{
	m_strUrlTemplate   = CGisMapGlobalConfig::GetAliyunUrl();
	m_strProxy = CGisMapGlobalConfig::GetAliyunProxy();

	m_dwTimeout   = CGisMapGlobalConfig::GetAliyunTimeout();
	m_dwProxyPort = CGisMapGlobalConfig::GetAliyunProxyPort();

	m_dwSuccessItil    = E_ITIL_GISMAPGATEWAYAO_ALIYUN_SUCC_NUM;
	m_dwRequestErrItil = E_ITIL_GISMAPGATEWAYAO_ALIYUN_REQUEST_FAILED_NUM;
	m_dwParseErrItil   = E_ITIL_GISMAPGATEWAYAO_ALIYUN_PARSE_FAILED_NUM;
	m_dwCheckErrItil   = E_ITIL_GISMAPGATEWAYAO_ALIYUN_CHECK_FAILED_NUM;
	m_dwInvalidErrItil = E_ITIL_GISMAPGATEWAYAO_ALIYUN_INVALID_NUM;

	m_strMapName = "ALIYUN";
}

void CAliyunRequest::RefleshProxy()
{
	CGisMapGlobalConfig::SwitchAliyunProxy();

	m_strProxy         = CGisMapGlobalConfig::GetAliyunProxy();
	m_dwProxyPort      = CGisMapGlobalConfig::GetAliyunProxyPort();
}


/* aliyun json format
 *{"cityName":"","address":"","level":1,"alevel":3,"lat":31.23039,"lon":121.47370}
 */
int CAliyunRequest::ParseJsonData(
	const std::string& strJson,
	SJsonAliyun& stJsonAliyun)
{
	if (strJson.length() > MAX_JSON_SIZE)
	{
		m_strErrMsg = "aliyun response json result length overflow";
		return ERR_ERP_GIS_GATEWAY_JSON_OVERFLOW;
	}

	try 
	{
		Json::Reader oJsonReader;
		Json::Value oRootValue(Json::objectValue);
		bool bParseSucc = oJsonReader.parse(strJson, oRootValue);
		if(!bParseSucc)
		{
			m_strErrMsg = "aliyun json reader paser err:" + oJsonReader.getFormatedErrorMessages();
			return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
		}

		if (oRootValue.empty())
		{
			m_strErrMsg = "aliyun json empty";
			return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
		}
		
		if (!oRootValue.isMember("level") ||
			oRootValue["level"].empty() ||
			!oRootValue["level"].isNumeric())
		{
			m_strErrMsg = "aliyun response json no level found";
			return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
		}
		stJsonAliyun.iLevel = oRootValue["level"].asInt();
		
		if (!oRootValue.isMember("alevel") ||
			oRootValue["alevel"].empty() ||
			!oRootValue["alevel"].isNumeric())
		{
			m_strErrMsg = "aliyun json alevel not found";
			return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
		}
		stJsonAliyun.iAlevel = oRootValue["alevel"].asInt();
		
		SPoints stPoints;
		if (!oRootValue.isMember("lon") ||
			oRootValue["lon"].empty() ||
			!oRootValue["lon"].isNumeric())
		{
			m_strErrMsg = "aliyun json lon not found";
			return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
		}
		stPoints.strX = DoubleToString(oRootValue["lon"].asDouble());

		if (!oRootValue.isMember("lat") ||
			oRootValue["lat"].empty() ||
			!oRootValue["lat"].isNumeric())
		{
			m_strErrMsg = "aliyun json lat not found";
			return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
		}
		stPoints.strY = DoubleToString(oRootValue["lat"].asDouble());
		stJsonAliyun.stPoints = stPoints;
	}
	catch (...)
	{
		m_strErrMsg = "catch exception, parse aliyun json failed.";
		return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
	}
	
	return 0;
}

int CAliyunRequest::ParseCoordinate(
	const std::string& strResponseBody,
	std::vector<CCoordinatesPo>& vecCoordinates)
{
	if (strResponseBody.empty())
	{
		m_strErrMsg = "aliyun response body empty.";
		return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
	}
	
	std::string strJson = GetJsonBody(strResponseBody);
	
	SJsonAliyun stJsonAliyun;
	int iRet = ParseJsonData(strJson, stJsonAliyun);
	if (0 != iRet)
	{
		return iRet;
	}
	
	if (!CheckJsonData(stJsonAliyun))
	{
		m_strErrMsg = "aliyun check json failed";		
		return ERR_ERP_GIS_GATEWAY_RESULT_CHECK_FAILED;
	}
	
	CCoordinatesPo oCoordinatePo;
	oCoordinatePo.SetXPoint(stJsonAliyun.stPoints.strX);
	oCoordinatePo.SetYPoint(stJsonAliyun.stPoints.strY);
	
	vecCoordinates.push_back(oCoordinatePo);
	
	return 0;
}

bool CAliyunRequest::CheckJsonData(const SJsonAliyun& stJsonAliyun)
{
	if (CGisMapGlobalConfig::GetAliyunCheckDataSwitch())
	{
		// aleve 精确度 （1 完全正确，2 比较正确 ，3 可能正确）
		// level 匹配级别（0 中国，1 省，2 地级市，3 县，4 乡镇，5街道，6 小区，7 具体的POI，8 门牌号级别，-1 查询失败）
		if (stJsonAliyun.iLevel <= 8 && stJsonAliyun.iLevel >= 6)
		{
			return true;
		}

		return false;
	}

	return true;
}

CGaodeRequest::CGaodeRequest():CGisMapRequest()
{
	m_strUrlTemplate   = CGisMapGlobalConfig::GetGaodeUrl();
	m_strProxy = CGisMapGlobalConfig::GetGaodeProxy();

	m_dwTimeout   = CGisMapGlobalConfig::GetGaodeTimeout();
	m_dwProxyPort = CGisMapGlobalConfig::GetGaodeProxyPort();

	m_dwSuccessItil    = E_ITIL_GISMAPGATEWAYAO_GAODE_SUCC_NUM;
	m_dwRequestErrItil = E_ITIL_GISMAPGATEWAYAO_GAODE_REQUEST_FAILED_NUM;
	m_dwParseErrItil   = E_ITIL_GISMAPGATEWAYAO_GAODE_PARSE_FAILED_NUM;
	m_dwCheckErrItil   = E_ITIL_GISMAPGATEWAYAO_GAODE_CHECK_FAILED_NUM;
	m_dwInvalidErrItil = E_ITIL_GISMAPGATEWAYAO_GAODE_INVALID_NUM;

	m_strMapName = "GAODE";
}

void CGaodeRequest::RefleshProxy()
{
	CGisMapGlobalConfig::SwitchGaodeProxy();

	m_strProxy         = CGisMapGlobalConfig::GetGaodeProxy();
	m_dwProxyPort      = CGisMapGlobalConfig::GetGaodeProxyPort();
}


/* gaode json format
 * {list:[{level:GL_TOWN, score:1, x:11 y:12], {level:GL_TOWN, score:1, x:11 y:12]}
 */
int CGaodeRequest::ParseJsonData(
	const std::string& strJson,
	std::vector<SJsonGaode>& vecJsonGaode)
{
	if (strJson.length() > MAX_JSON_SIZE)
	{
		m_strErrMsg = "gaode response json result length overflow";
		return ERR_ERP_GIS_GATEWAY_JSON_OVERFLOW;
	}

	try 
	{
		Json::Reader oJsonReader;
		Json::Value oRootValue(Json::objectValue);
		bool bParseSucc = oJsonReader.parse(strJson, oRootValue);
		if(!bParseSucc)
		{
			m_strErrMsg = "gaode json reader paser err:" + oJsonReader.getFormatedErrorMessages();
			return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
		}
		C2C_WW_LOG_DEBUG("oJsonReader.parse OK");

		if (oRootValue.empty())
		{
			m_strErrMsg = "gaode json empty";
			return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
		}
		
		if (!oRootValue.isMember("list"))
		{
			m_strErrMsg = "gaode response json no list found";
			return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
		}
		Json::Value oListValue = oRootValue["list"];
		if (!oListValue.empty() && oListValue.isArray())
		{
			for (uint32_t dwIdx = 0; dwIdx < oListValue.size(); dwIdx++)
			{
				Json::Value oItemValue = oListValue[dwIdx];
				if (oItemValue.empty() || 
					!oItemValue.get("level", "").isString() ||
					!oItemValue.get("score", "0").isString() ||
					!oItemValue.get("x", "").isString() ||
					!oItemValue.get("y", "").isString())
				{
					continue;
				}

				SJsonGaode stJsonGaode;
				stJsonGaode.strLevel = oItemValue.get("level", "").asString();
				stJsonGaode.dbScore  = atof(oItemValue.get("score", "0").asString().c_str());
				stJsonGaode.stPoints.strX = oItemValue.get("x", "").asString();
				stJsonGaode.stPoints.strY = oItemValue.get("y", "").asString();

				vecJsonGaode.push_back(stJsonGaode);
			}
		}
	}
	catch (...)
	{
		m_strErrMsg = "catch exception, parse gaode json failed.";
		return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
	}
	
	return 0;
}

int CGaodeRequest::ParseCoordinate(
	const std::string& strResponseBody,
	std::vector<CCoordinatesPo>& vecCoordinates)
{
	if (strResponseBody.empty())
	{
		m_strErrMsg = "gaode response body empty.";
		return ERR_ERP_GIS_GATEWAY_PARSE_FAILED;
	}
	
	std::string strJson = GetJsonBody(strResponseBody);
	
	std::vector<SJsonGaode> vecJsonGaode;
	int iRet = ParseJsonData(strJson, vecJsonGaode);
	if (0 != iRet)
	{
		return iRet;
	}

	FilterJsonData(vecJsonGaode);
	if (vecJsonGaode.empty())
	{
		m_strErrMsg = "check gaode jason failed.";
		
		return ERR_ERP_GIS_GATEWAY_RESULT_CHECK_FAILED;
	}

	std::vector<SJsonGaode>::const_iterator iter = vecJsonGaode.begin();
	std::vector<SJsonGaode>::const_iterator iterEnd = vecJsonGaode.end();
	for (; iter != iterEnd; iter++)
	{
		CCoordinatesPo oCoordinatePo;
		oCoordinatePo.SetXPoint(iter->stPoints.strX);
		oCoordinatePo.SetYPoint(iter->stPoints.strY);
	
		vecCoordinates.push_back(oCoordinatePo);
	}
	
	return 0;
}

void CGaodeRequest::FilterJsonData(std::vector<SJsonGaode>& vecJsonGaode)
{
	if (!CGisMapGlobalConfig::GetGaodeCheckDataSwitch())
	{
		return;
	}

	uint32_t dwInvalidLevelSize = sizeof(strInvalidGaodeLevel)/sizeof(strInvalidGaodeLevel[0]);

	std::vector<SJsonGaode> vecJsonGaodeTmp;
	std::vector<SJsonGaode>::const_iterator iter = vecJsonGaode.begin();
	std::vector<SJsonGaode>::const_iterator iterEnd = vecJsonGaode.end();
	for (; iter != iterEnd; iter++)
	{
		if (iter->dbScore > 0.46 && !IsInArray(strInvalidGaodeLevel, dwInvalidLevelSize, iter->strLevel))
		{
			vecJsonGaodeTmp.push_back(*iter);
		}
	}

	vecJsonGaode = vecJsonGaodeTmp;
}
